package com.pmcc.platform.base.service;

import com.pmcc.core.config.security.JwtUser;
import com.pmcc.platform.base.entity.FileEntity;
import com.pmcc.platform.base.repository.FileManageRepository;
import com.pmcc.platform.base.vo.FileEntityVO;
import com.pmcc.utils.*;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.domain.Page;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;

@Service
@Transactional
public class FileManageService {

    @Value("${upload.path}")
    private String path;

    @Value("${upload.readPath}")
    private String readPath;

    @Value("${baseConfig.serviceIp}")
    private String serviceIp;

    @Autowired
    FileManageRepository fileManageRepository;


    /**
     * 根据登录人，查询其创建角色
     *
     * @param antPage
     * @return
     */
    public ResultBean queryByPage(AntPage antPage, FileEntity model) {
        ResultBean resultBean = new ResultBean();
        antPage.setOrder(AntPage.DESC);
        antPage.setSort("createTime");
        Page<FileEntity> page = fileManageRepository.findAll(this.getSpecification(model), antPage.getPageRequest());

        List<FileEntityVO> voList = new ArrayList<>();
        for (FileEntity fileEntity : page.getContent()) {
            FileEntityVO vo = new FileEntityVO();
            BeanUtils.copyProperties(fileEntity, vo);
            vo.setFileUrl(serviceIp+vo.getFileUrl());
            vo.setFileQRUrl(serviceIp+vo.getFileQRUrl());
            voList.add(vo);
        }

        resultBean.setRows(voList);
        resultBean.setPage(antPage.getPage());
        resultBean.setPageSize(antPage.getPageSize());
        resultBean.setTotal(page.getTotalElements());
        resultBean.setResultCode(ResultBean.SUCCESS);
        return resultBean;
    }


    private Specification<FileEntity> getSpecification(FileEntity model) {
        return (Root<FileEntity> root, CriteriaQuery<?> query, CriteriaBuilder builder) -> {
            List<Predicate> list = new ArrayList<Predicate>();

            if (StringUtils.isNotEmpty(model.getFileName())) {
                list.add(builder.like(root.get("fileName").as(String.class), "%" + model.getFileName().trim() + "%"));
            }

            if (StringUtils.isNotEmpty(model.getFileType())) {
                list.add(builder.like(root.get("fileType").as(String.class), "%" + model.getFileType().trim() + "%"));
            }

            if (StringUtils.isNotEmpty(model.getCreateId())) {
                list.add(root.get("createId").in(Arrays.asList(model.getCreateId().split(","))));
            }
            list.add(builder.equal(root.get("delFlag").as(String.class), "0"));
            Predicate[] p = new Predicate[list.size()];
            return builder.and(list.toArray(p));
        };
    }

    public ResultBean delete(String id) {
        ResultBean resultBean = new ResultBean();
        FileEntity obj = fileManageRepository.findOne(id);

        // todo 删除 本地文件
        File file = new File(obj.getFileMacUrl());

        if (file.exists() && file.isFile()) {
            if (!file.delete()) {
                resultBean.setResultCode(ResultBean.FAIL);
                resultBean.setResultDesc("删除失败！");
                return resultBean;
            }
        }
        fileManageRepository.delete(obj);
        resultBean.setResultCode(ResultBean.SUCCESS);
        return resultBean;
    }


    /**
     * 单文件上传 不保存附件表的方法
     *
     * @param file 文件
     * @return
     */
    public ResultBean uploadFile(MultipartFile file) {
        ResultBean resultBean = new ResultBean();
        // 原文件名称
        String originalFilename = file.getOriginalFilename();
        String[] arr = originalFilename.split("\\.");
        // 文件类型
        String fileType = arr.length > 1 ? arr[arr.length - 1] : "";

        String imgType = "webp,svg,png,gif,jpg,jpeg,bmp,WEBP,SVG,PNG,GIF,JPG,JPEG,BMP";
        if (StringUtils.isNotEmpty(fileType) && imgType.contains(fileType)) {
            fileType = fileType.toLowerCase();
        }
        // 存放在服务器端的文件名
        String serverFileName = StringUtils.isEmpty(fileType) ? UUIDGenerator.getUUID() : UUIDGenerator.getUUID() + "." + fileType;//附件上传上去后的随机名称
        // 创建文件夹  年-月-日
        String folder = DateUtil.DateToString(new Timestamp(new Date().getTime()), "yyyy-MM-dd");
        // 数据库存放路径：文件名/年-月-日
        String filePath = "fileManage/" + folder + "/";

        // 服务器存放附件文件夹
        File targetFile = new File(path, filePath);
        boolean flag = true;
        if (!targetFile.exists()) {
            flag = targetFile.mkdirs();
        }
        if (flag) {
            try {
                byte[] bytes = file.getBytes();
                BufferedOutputStream stream = new BufferedOutputStream(new FileOutputStream(new File(path + filePath + serverFileName)));
                stream.write(bytes);
                stream.close();

                JwtUser jwtUser = (JwtUser) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
                FileEntity model = new FileEntity();
                model.setFileName(originalFilename);
                model.setFileAliasName(serverFileName);
                model.setFileType(fileType);
                model.setFileMacUrl(path + filePath + serverFileName);
                model.setFileUrl(readPath + filePath + serverFileName);
                model.setFileSize(file.getSize());
                model.setDelFlag("0");
                model.setCreateId(jwtUser.getId());
                model.setCreateTime(new Date());
                model.setCreateName(jwtUser.getUserCName());
                fileManageRepository.save(model);

                model.setFileQRUrl(this.createQR(model));
                resultBean.setResultCode(ResultBean.SUCCESS);
                resultBean.setResultDesc("上传成功！");
            } catch (Exception e) {
                resultBean.setResultCode(ResultBean.FAIL);
                resultBean.setResultDesc("上传失败！");
                e.printStackTrace();
            }
        } else {
            resultBean.setResultCode(ResultBean.FAIL);
            resultBean.setResultDesc("上传失败！");
        }
        return resultBean;
    }

    private String createQR(FileEntity model) {
        String basePath = "fileManage/QR/" + DateUtil.DateToString(new Date(), DateUtil.YYYY_MM_DD) + "/";
        QRCodeUtils.formatEncode(680, 680, path + basePath, model.getId(), "jpg", serviceIp + model.getFileUrl(), null);
        return readPath + basePath + model.getId() + ".jpg";
    }
}
